home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
cpp_libs
/
answrbok
/
8_5.lha
/
8_5
/
doprint.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-08-08
|
3KB
|
139 lines
* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */
* The C++ Answer Book */
* Tony Hansen */
* All rights reserved. */
/ _doprint(): low level function for doing
/ formatted output, to be invoked by the
/ v*printf() family of functions
include <string.h>
/ endchar() returns TRUE for those format
/ characters which cause output.
nt endchar(char c)
switch (c)
{
case 'd': case 'i': case 'o': case 'u':
case 'x': case 'X': case 'f': case 'e':
case 'E': case 'g': case 'G': case 'c':
case 's': case 'p': case 'n': case '%':
case 0:
return 1;
default:
return 0;
}
nt _doprint(ostream *out, const char *fmt, va_list vl)
if (!fmt)
return EOF;
char *cfmt = new char[strlen(fmt)+1];
while (*fmt)
{
char *buf = cfmt;
int asterisks = 0;
int shortarg = 0;
int longarg = 0;
char c;
// loop looking for the beginning of a format
while ((c = *buf++ = *fmt++) && (c != '%'))
;
// loop looking for the end of the format
if (c)
while (!endchar(c = *buf++ = *fmt++))
if (c == '*') asterisks++;
else if (c == 'h') shortarg++;
else if (c == 'l') longarg++;
// polish off the buffer. leave fmt
// pointing at the null if just past it.
*buf = '\0';
if (!c)
fmt--;
// pull off the width and precision
int prec = 0, width = 0;
switch (asterisks)
{
case 0: break;
case 2: width = va_arg(vl, int); // NO BREAK
case 1: prec = va_arg(vl, int); break;
}
/ Declare a generic output routine for the type passed
/ on the stack and the type used for output. This
/ cannot be an inline since the parameters are types.
define OUTPUT(parmtype, outtype) \
do { \
outtype val = va_arg(vl, parmtype); \
switch (asterisks) \
{ \
case 0: \
(*out) << form(cfmt, val); break; \
case 1: \
(*out) << form(cfmt, prec, val); break; \
case 2: \
(*out) << form(cfmt,width,prec,val);break; \
} \
} while (0)
// extract the value and output it
switch (c)
{
// decimal variables
case 'd': case 'i':
if (longarg)
OUTPUT(long, long);
else if (shortarg)
OUTPUT(short, int);
else
OUTPUT(int, int);
break;
// unsigned decimal variables
case 'o': case 'u': case 'x': case 'X':
if (longarg)
OUTPUT(unsigned long, unsigned long);
else if (shortarg)
OUTPUT(unsigned short, unsigned int);
else
OUTPUT(unsigned int, unsigned int);
break;
// double variables
case 'f': case 'e': case 'E':
case 'g': case 'G':
OUTPUT(double, double);
break;
// character variables
case 'c':
OUTPUT(unsigned char, int);
break;
// string variable
case 's':
OUTPUT(char*, char*);
break;
// nothing much here
case '%': case 0:
(*out) << form(cfmt);
break;
}
}
delete cfmt;
return 1;